#include "queue.h"
#include <iostream>
template <class T>
Queue<T>::Queue()
{
    // TODO
    //类的默认构造器，会对类中变量的值进行初始化
    len = 0;
    front_ = new Node<T>();
    front_ = NULL;
    back_ = new Node<T>();
    back_ = NULL;
}

template <class T>
Queue<T>::Queue(Queue &other)
{
    this->len = *(new int(other.len));//复制了len
    this->back_ = new Node<T>(*other.back_);//只复制了ptr,next为空
    
    Node<T>* this_back=this->back_;//定义临时变量
    Node<T>* other_back=other.back_;

    //创造与众不同的相同
    while (1)
    {
        other_back = other_back->get_next();
        if (other_back == NULL)
            break;
        this_back->set_next(new Node<T>(*other_back));
        this_back = this_back->get_next();
    }
    this->front_ = this_back;
}

template <class T>
Queue<T>::~Queue()
{
    // TODO
    //类的析构函数，会摧毁队列释放内存
    while (1)
    {
        Node<T> *t = pop();
        if (t == NULL)
            break;
        delete (t);
    }
    delete (front_);
    delete (back_);
}

template <class T>
Queue<T> &Queue<T>::operator=(Queue &other)
{
    // TODO
    //重载=操作符，将一个队列的内容复制给另外一个队列
    if (&other != this)
    {
        this->len = other.len;
        this->back_ = other.back_;
        this->front_ = other.front_;
    }
    return this;
}


template <class T>
int Queue<T>::get_size() const
{
    // TODO
    //获取数据结构内元素的个数
    return len;
    return 0;
}

template <class T>
void Queue<T>::push(T *t)
{
    // TODO
    //这个函数会把泛型T指针包装到一个Node类里然后推入数据结构。空指针不会被接受
    if (t == NULL)
        return;
    Node<T> *new_Node = new Node<T>(t);
    if (len == 0)
    {
        new_Node->set_next(NULL);
        front_ = new_Node;
        back_ = new_Node;
        len++;
        return;
    }
    new_Node->set_next(back_);
    back_ = new_Node;
    len++;
}

template <class T>
void Queue<T>::push(Node<T> *n)
{
    // TODO
    //这个函数与前一个功能完全相同，但是它的参数是Node类指针
    if (n == NULL)
        return;
    if (len == 0)
    {
        front_ = n;
        n->set_next(NULL);
        back_ = n;
        len++;
        return;
    }
    n->next = back_;
    back_ = n;
    len++;
}

template <class T>
Node<T> *Queue<T>::pop()
{
    // TODO
    //顾名思义，从队列中取出第一个元素。如果队列是空的则返回空指针
    if (len == 0)
        return NULL;
    Node<T> *this_front = front_;
    Node<T> *this_back = back_;
    for (int i = 1; i < len; i++)
    {
        if (this_back->get_next() == front_)
            break;
        this_back = this_back->get_next();
    }
    len = len - 1;
    front_ = this_back;
    front_->set_next(NULL);
    return this_front;
}

template <class T>
void Queue<T>::print()
{
    // TODO
    //打印函数，警告：你必须按�? 从左到右的顺序打印从后部到前部的元素，按照如下的格式：[%d]->[%d]->END
    //也就是说Node包含的内容（这里举整数型做例子，但是也可以是其它类型比如字符串）由方括号包裹
    //之间�?->连接，用END表示结束
    Node<T> *p = back_;
    while (1)
    {
        if (p == NULL)
        {
            std::cout << "END" << std::endl;
            return;
        }
        p->print();
        p = p->get_next();
    }
}
